﻿// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "Interfaces/IPv4/IPv4Endpoint.h"
#include "TCPConnection.generated.h"

/**
 * 服务器端：
 * 		基础流程：
 * 			1.创建Socket
 * 			2.绑定固定地址和端口
 * 			3.监听
 * 			4.接受客户端链接
 * 			5.接受/发送消息
 * 			6.关闭Socket
 * 			socket->bind->listen->accept->send/recv->closesocket
 * 		服务端Socket变化：
 * 			1.生成Socket（链接Socket）
 * 			2.链接Socket内添加ip和端口信息
 * 			3.将链接Socket从主动连接变为被动连接
 * 			4.当客户端有链接请求来的时候，链接Socket调用accept函数将生成一个新Socket（通信Socket）用来和客户端的Socket通信，而链接Socket只接受连接请求，不参与数据的交换
 * 			5.通信Socket与客户端通信
 * 			6.关闭链接Socket
 * 				
 * 	客户端：
 * 		基础流程：
 * 			1.创建Socket
 * 			2.根据ip和端口连接服务端
 * 			3.发送/接受消息
 * 			4.关闭Socket
 * 			socket->[bind->]->connect->send/recv->closesocket
 **/


UCLASS()
class MISCELLANEOUSPROJECT_API ATCPConnection : public AActor
{
	GENERATED_BODY()

public:
	// Sets default values for this actor's properties
	ATCPConnection();

protected:
	// Called when the game starts or when spawned
	virtual void BeginPlay() override;

public:

	FSocket* ListenerSocket;
	FSocket* ConnectionSocket;
	FIPv4Endpoint RemoteAddressForConnection;

	bool StartTCPReceiver(const FString& YourChosenSocketName, const FString& TheIP, const int32 ThePort);

	FSocket* CreateTCPConnectionListener(const FString& YourChosenSocketName, const FString& TheIP, const int32 ThePort, const int32 ReceiveBufferSize = 2 * 1024 * 1024);

	//Timer functions, could be threads
	void TCPConnectionListener(); //can thread this eventually
	void TCPSocketListener(); //can thread this eventually


	//Format String IP4 to number array
	bool FormatIP4ToNumber(const FString& TheIP, uint8 (&Out)[4]);

	//Rama's StringFromBinaryArray
	FString StringFromBinaryArray(TArray<uint8>& BinaryArray);

	UFUNCTION(BlueprintCallable)
	void TCPLaunch();
};
